package com.spx.core.services.security;

import java.lang.reflect.Method;

import org.apache.commons.lang.StringUtils;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;

import com.spx.core.CoreActivator;
import com.spx.core.services.ActivityLabel;
import com.spx.core.types.Activity;
import com.spx.core.types.User;
import com.spx.kernel.KernelActivator;

public class AuthorizationUtil
{

	private static void addctivityJob(final String activityName)
	{
		Job job = new Job("Activity Adder")
		{

			@Override
			protected IStatus run(IProgressMonitor monitor)
			{
				System.out.println("Hello World (from a background job)");
				Activity newActivity = new Activity();
				newActivity.setName(activityName);
				KernelActivator.getDefault().getPersistService().persist(newActivity);
				return Status.OK_STATUS;
			}
		};
		job.setPriority(Job.SHORT);
		job.schedule(1000);
	}

	public static void authorize(Method method) throws AuthorizationException
	{

		ActivityLabel activityLabel = method.getAnnotation(ActivityLabel.class);
		authorize(activityLabel);

	}

	public static void authorize(Class<?> clazz)
	{
		ActivityLabel activityLabel = clazz.getAnnotation(ActivityLabel.class);
		authorize(activityLabel);

	}

	public static boolean isAuthorized(Class<?> clazz)
	{
		boolean result = true;
		try
		{
			ActivityLabel activityLabel = clazz.getAnnotation(ActivityLabel.class);
			authorize(activityLabel);
		} catch (Throwable e)
		{
			result = false;
		}
		return result;
	}

	private static void authorize(ActivityLabel activityLabel)
	{
		if (activityLabel != null)
		{

			User presentUser = CoreActivator.getDefault().getSecurityService().getPresentUser();
			if (presentUser != null && StringUtils.equals(presentUser.getName(), "root"))
			{
				return;
			}

			Activity presentActivity = CoreActivator.getDefault().getSecurityService().findActivity(activityLabel.name());
			if (presentActivity == null)
			{
				addctivityJob(activityLabel.name());
				NoSuchActivityException ae = new NoSuchActivityException();
				ae.setActivityName(activityLabel.name());
				throw ae;
			}

			// User must have logged in
			if (presentUser == null)
			{
				throw new NoUserException();
			}
			if (presentUser.canPerform(presentActivity.getName()) == false)
			{

				UnAuthorisedActivityException uae = new UnAuthorisedActivityException();
				uae.setUser(presentUser);
				uae.setActivity(presentActivity);
				throw uae;
			}

		}
	}
}
